#pragma once

namespace fastbird
{
	static const float PI = 3.14159265358979f;
	static const float HALF_PI = 1.5707963f;
	static const float TWO_PI = 6.28318530f;
	static const float EPSILON = 1.192092896e-07F;
	static const float ZERO_TOLERANCE = 1e-06f;
	static const float ROOT_2 = 1.41421356237f;
	static const float INV_ROOT_2 = 0.7071067811865475244f;
	static const float ROOT_3 = 1.73205080757f;


	inline bool IsNaN(float f)
	{
		return f != f;
	}

	inline float Degree(float radian)
	{
		return radian / PI * 180.0f;
	}

	inline float Radian(float degree)
	{
		return degree / 180.0f * PI;
	}

	inline bool IsPowerOfTwo(int a)
	{
		return !(a & (a-1) );
	}

	inline unsigned long GetNextPowerOfTwo(unsigned long Value)
	{
		if(Value)
		{
			Value--;
			Value = (Value >> 1) | Value;
			Value = (Value >> 2) | Value;
			Value = (Value >> 4) | Value;
			Value = (Value >> 8) | Value;
			Value = (Value >> 16) | Value;
		}
		return Value + 1;
	}

	template <class T>
	inline void Clamp(T& a, const T min, const T max)
	{
		if (a < min)
			a = min;
		else if (a>max)
			a = max;
	}

	template <class T>
	inline T ClampRet(const T a, const T min, const T max)
	{
		T ret = a;
		Clamp(ret, min, max);
		return ret;
	}

	//-------------------------------------------------------------------------
	template <class T>
	inline T Lerp(const T& a, const T& b, float lp)
	{
		return a * (1.0f-lp) + b * lp;
	}

	//-------------------------------------------------------------------------
	inline float ACos (float fValue)
	{
		if ( -1.0 < fValue )
		{
			if ( fValue < 1.0 )
				return acos(fValue);
			else
				return 0.0f;
		}
		else
		{
			return PI;
		}
	}

	//-------------------------------------------------------------------------
	inline bool IsOverlapped(const RECT& a, const RECT& b)
	{
		if (a.right < b.left || a.left > b.right ||
			a.bottom < b.top || a.top > b.bottom)
			return false;

		return true;
	}
}